package com.thomasmoerman.dci3.tmc

import com.thomasmoerman.dci3.domain._
import com.thomasmoerman.dci3.frw._
import org.hibernate.Session

trait MoneySource { 
  
  class InsufficientFundsException extends RuntimeException
  
  def transferMoney(recipient: MoneySink, amount: Double)
  
}

trait MoneySourceProvider {
  
  object MoneySourceConversion {
	implicit def convert(account: Account): MoneySource = asMoneySource(account)  
  }
  
  def asMoneySource(account: Account): MoneySource
  
}

trait TransactionalMoneySourceProvider extends MoneySourceProvider {
  this: Transactional with CalculatedBalanceAspect =>
  
  def asMoneySource(account: Account): MoneySource = new TransactionalMoneySource(account)
  
  class TransactionalMoneySource(self: Account) extends CalculatedBalance(self) with MoneySource {
	  
	def transferMoney(recipient: MoneySink, amount: Double) {
	  def checkBalance = if (amount > balance) throw new InsufficientFundsException
	  
	  inTransaction() {
	 	checkBalance
    	
        self.decreaseBalance(amount)
        
        recipient.increaseBalance(amount)
        
        self.updateLog("balance decreased with $", amount)
      
        recipient.updateLog("balance increased with $", amount)
      }
	}
	
  }
	
}